<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\App\WorkContact\Action\Workbench;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\WorkbenchAuthMiddleware;
use MoChat\App\User\Contract\UserContract;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Contract\WorkContactTagContract;
use MoChat\App\WorkContact\Contract\WorkContactTagPivotContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;

/**
 * 客户列表.
 * @Controller
 */
class ContactIndex extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var WorkContactTagPivotContract
     */
    protected $workContactTagPivotService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var UserContract
     */
    protected $userService;

    /**
     * @Inject
     * @var WorkContactTagContract
     */
    protected $workContactTagService;

    /**
     * @Middlewares({
     *     @Middleware(WorkbenchAuthMiddleware::class)
     * })
     * @RequestMapping(path="/workbench/workContact/contactIndex", methods="GET")
     * @return array 返回数组
     */
    public function handle(): array
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpId'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $params = [
            'name' => $this->request->input('name', ''),
            'employeeId' => (int) $this->request->input('employeeId', 0),
            'tags' => $this->request->input('tags', []),
            'startTime' => $this->request->input('startTime', ''),
            'endTime' => $this->request->input('endTime', ''),
            'channel' => $this->request->input('channel', ''),
            'gender' => (int) $this->request->input('gender', 3),
            'status' => $this->request->input('status', 0),
            'page' => $this->request->input('page', 1),
            'perPage' => $this->request->input('perPage', 10),
        ];
        $params['corpId'] = $user['corpId'];
        $params['userEmployeeId'] = $user['id'];
        $params['userId'] = $user['logUserId'];

        // 参数验证
        $this->validated($params);

        // 客户
        return $this->getContact($params);
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
        ];
    }

    private function getContact($params): array
    {
        $contactIds = [];
        // 组织响应数据
        $data = [
            'page' => [
                'perPage' => $params['perPage'],
                'total' => 0,
                'totalPage' => 0,
            ],
            'list' => [],
        ];
        $search = [
            'corpId' => $params['corpId'],
            'employeeIds' => $params['employeeId'] > 0 ? [$params['employeeId']] : [$params['userEmployeeId']],
            'startTime' => $params['startTime'],
            'endTime' => $params['endTime'],
            'addWay' => $params['channel'],
            'status' => $params['status'], ];
        if ($params['userId'] > 0) {
            $userInfo = $this->userService->getUserById($params['userId'], ['is_root']);
            $userInfo['isRoot'] === 1 && $search['employeeId'] = 0;
        }

        $contactEmployees = $this->workContactEmployeeService->getWorkContactEmployeesBySearch($search, ['contact_id', 'create_time', 'employee_id']);
        empty($contactEmployees) || $contactIds = array_unique(array_column($contactEmployees, 'contactId'));
        empty($contactEmployees) || $contactEmployees = array_column($contactEmployees, null, 'contactId');

        if (! empty($contactIds)) {
            $contacts = $this->workContactService->getWorkContactsByIdsNameGender($contactIds, $params['name'], $params['gender'], ['perPage' => $params['perPage'], 'page' => $params['page']], ['id', 'name', 'avatar']);
            foreach ($contacts['data'] as &$item) {
                $item['tags'] = [];
                $contactTags = $this->workContactTagPivotService->getWorkContactTagPivotsByContactId($item['id'], ['contact_tag_id']);
                if (! empty($contactTags)) {
                    $tags = $this->workContactTagService->getWorkContactTagsById(array_unique(array_column($contactTags, 'contactTagId')), ['name']);
                    if (! empty($tags)) {
                        $item['tags'] = array_column($tags, 'name');
                    }
                }
                $item['avatar'] = file_full_url($item['avatar']);
                $employee = [];
                if (! empty($contactEmployees[$item['id']])) {
                    $employee = $this->workEmployeeService->getWorkEmployeeById($contactEmployees[$item['id']]['employeeId'], ['id', 'name', 'avatar']);
                }
                $item['employeeName'] = empty($employee) ? '' : $employee['name'];
                $item['employeeAvatar'] = empty($employee) ? '' : file_full_url($employee['avatar']);
                $item['createTime'] = empty($contactEmployees[$item['id']]) ? '' : $contactEmployees[$item['id']]['createTime'];
            }
            unset($item);
            // 处理分页数据
            $data['page']['total'] = $contacts['total'];
            $data['page']['totalPage'] = $contacts['last_page'];
            $data['list'] = $contacts['data'];
        }
        return $data;
    }
}
